package cn.yto.print.system.version;

import cn.yto.print.config.i18n.I18nResourceManager;
import cn.yto.print.constants.AssistantConstants;
import cn.yto.print.model.dto.KhgjVersionDTO;
import cn.yto.print.socket.PrintSocketEndpoint;
import cn.yto.print.utils.FxToastUtil;
import de.felixroske.jfxsupport.GUIState;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.prefs.Preferences;

public class SystemUpdateChecker {

    // Windows 下 Preferences 类最终将数据保存在注册表中
    private static final Preferences PREFS = Preferences.userNodeForPackage(SystemUpdateChecker.class);

    private static final I18nResourceManager I18N = I18nResourceManager.getInstance();

    /**
     * 检查是否有新版本更新
     */
    public static void checkForUpdate(boolean showToast) {
        // 从服务器获取版本信息
        KhgjVersionDTO versionInfo = KhgjContactManager.getVersionUpdate();
        Optional.ofNullable(versionInfo).map(v -> {
            if ("0".equals(v.getUpgradeStatus())) {
                PREFS.put(AssistantConstants.UPGRADE_NEED_PREF, "0");
                if (showToast) {
                    Platform.runLater(() ->
                            FxToastUtil.showToast(I18N.get("version.update.toast"))
                    );
                }
                return null;
            }

            String currentVersion = System.getProperty(AssistantConstants.APP_VERSION);
            // 比较两个版本号
            int comparison = compareVersion(currentVersion, v.getSoftwareVersion());
            if (comparison > 0) {
                PREFS.put(AssistantConstants.UPGRADE_NEED_PREF, "1");
                List<ButtonType> buttonTypes = new ArrayList<>();
                ButtonType updateButton = new ButtonType(I18N.get("version.update.confirm"));
                buttonTypes.add(updateButton);
                if ("1".equals(v.getUpgradeStatus())) {
                    buttonTypes.add(new ButtonType(I18N.get("version.update.cancel")));
                }
                Platform.runLater(() -> {
                    String content = String.format(
                            I18N.get("version.update.tooltip"),
                            currentVersion,
                            v.getSoftwareVersion(),
                            v.getUpgradeContent()
                    );

                    Optional<ButtonType> reaction = showVersionAlert(content, buttonTypes.toArray(new ButtonType[0]));
                    if (reaction.isPresent() && reaction.get() == updateButton) {
                        DownloadPrintPlugin.startDownloadProcess(v.getFileUrl());
                    } else if ("2".equals(v.getUpgradeStatus())) {
                        // 强制更新且用户未确认，直接退出
                        Platform.exit();
                        System.exit(0);
                    }
                });

            } else {
                PREFS.put(AssistantConstants.UPGRADE_NEED_PREF, "0");
            }
            return null;
        }).orElseGet(() -> null);
    }

    /**
     * 比较两个版本号
     */
    public static int compareVersion(String currentVersion, String latestVersion) {
        String[] currentParts = currentVersion.split("\\.");
        String[] latestParts = latestVersion.split("\\.");
        int length = Math.max(currentParts.length, latestParts.length);

        for (int i = 0; i < length; i++) {
            int currentPart = (i < currentParts.length) ? Integer.parseInt(currentParts[i]) : 0;
            int latestPart = (i < latestParts.length) ? Integer.parseInt(latestParts[i]) : 0;
            if (currentPart < latestPart) {
                return 1;
            } else if (currentPart > latestPart) {
                return -1;
            }
        }
        return 0;
    }

    /**
     * 显示版本更新提示框
     */
    public static Optional<ButtonType> showVersionAlert(String content, ButtonType... buttonTypes) {
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
        alert.getDialogPane().getStylesheets().add("css/alert.css");
        alert.initStyle(StageStyle.UNDECORATED);

        alert.setTitle(I18N.get("version.update.title"));
        alert.setHeaderText(null);
        alert.setContentText(content);
        alert.getButtonTypes().setAll(buttonTypes);
        Stage stage = GUIState.getStage();

        alert.initOwner(stage);
        alert.initModality(Modality.APPLICATION_MODAL);
        return alert.showAndWait();
    }

}

